package com.zxq.ruoyi.channel;

import com.alibaba.fastjson.JSON;
import com.zxq.ruoyi.config.LockConfig;
import com.zxq.ruoyi.domain.vo.DevCmdVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;


@Component
@Slf4j
public class SynchroniseMessage {


    /**
     * 锁配置
     */
    @Autowired
    LockConfig lockConfig;

    /**
     * 锁
     */
    ConcurrentHashMap<String,Object> locks = new ConcurrentHashMap<>();

    /**
     * 阻塞的数据容器
     */
    ConcurrentHashMap<String, DevCmdVo> blockData = new ConcurrentHashMap<>();


    /**
     * 阻塞平台消息，用来处理同步
     * @param devId 设备id
     * @param resultId 指令结果id
     * @return
     */
    @SneakyThrows
    public  DevCmdVo waitCmdMessage(String devId,Long resultId) {
        DevCmdVo result = null;
        String key =  generateCmdKey(devId,resultId);
        if(locks.get(key) == null) {
            locks.put(key,new Object());
        }
        Object object = locks.get(key);
        if(blockData.get(key) != null) {
            blockData.remove(key);
        }
        log.info(String.format("devId:%s block",devId));
        synchronized (object) {
            object.wait(lockConfig.getTimeOut());
            result = blockData.get(key);
        }
        log.info(String.format("devId:%s active",devId));
        return result;
    }

    /**
     * 唤醒平台消息，用来处理同步
     * @param devCmdVo 设备指令操作
     */
    public  Boolean notifyPlatformMessage(String devId,Long resultCmd,DevCmdVo devCmdVo) {
       String key = generateCmdKey(devId,resultCmd);
       if(locks.get(key) == null) {
           log.info(String.format("devId:%s key:%s not find unit lock,please check your mysql data!", devId, key));
           return false;
       }
       blockData.put(key,devCmdVo);
       Object object =  locks.get(key);
       if (object == null) {
           log.info("object is null!");
           return false;
       }
       synchronized (object) {
            object.notify();
        }
       return true;
    }



    static String blockKey = "dev:%s-cmd:%s";
    /**
     * 生产阻塞的key，阻塞当前线程
     * @param devId 设备id
     * @param cmdId 指令id
     * @return
     */
    private static String generateCmdKey(String devId,Long cmdId) {
        String key = String.format(blockKey,devId,cmdId);
        return key;
    }






}
